﻿using DG.Tweening;
using UnityEngine;
using UnityEngine.UI;

public class ScrollerArrowController : USaBehaviour
{
    [SerializeField]
    private bool useTween = true;
    [SerializeField]
    private Transform upArrow;
    [SerializeField]
    private Transform downArrow;
    [SerializeField]
    private Transform rightArrow;
    [SerializeField]
    private Transform leftArrow;
    [SerializeField, Tooltip("低于阈值时隐藏箭头"), Range(0f, 0.5f)]
    private float dead = 0.02f;

    private ScrollRect m_ScrollRect;
    private bool m_HorizontalEnabled, m_VerticalEnabled;
    private float m_PreviousContentSizeX, m_PreviousContentSizeY;

    private void Start()
    {
        m_ScrollRect = GetComponent<ScrollRect>();
        m_HorizontalEnabled = m_ScrollRect.horizontal;
        m_VerticalEnabled = m_ScrollRect.vertical;
        if (rightArrow == null || leftArrow == null)
            m_HorizontalEnabled = false;
        if (upArrow == null || downArrow == null)
            m_VerticalEnabled = false;
        if (m_HorizontalEnabled)
        {
            leftArrow.gameObject.SetActive(false);
            rightArrow.gameObject.SetActive(false);
            if (useTween)
            {
                leftArrow.DOScale(0.7f, 0.5f).SetLoops(-1, LoopType.Yoyo).SetUpdate(true).SetLink(gameObject);
                rightArrow.DOScale(0.7f, 0.5f).SetLoops(-1, LoopType.Yoyo).SetUpdate(true).SetLink(gameObject);
            }
        }
        if (m_VerticalEnabled)
        {
            upArrow.gameObject.SetActive(false);
            downArrow.gameObject.SetActive(false);
            if (useTween)
            {
                upArrow.DOScale(0.7f, 0.5f).SetLoops(-1, LoopType.Yoyo).SetUpdate(true).SetLink(gameObject);
                downArrow.DOScale(0.7f, 0.5f).SetLoops(-1, LoopType.Yoyo).SetUpdate(true).SetLink(gameObject);
            }
        }
        m_ScrollRect.onValueChanged.AddListener(OnScroll);
    }

    private void Update()
    {
        if (m_HorizontalEnabled)
        {
            if (m_PreviousContentSizeX != m_ScrollRect.content.sizeDelta.x)
            {
                m_PreviousContentSizeX = m_ScrollRect.content.sizeDelta.x;
                CheckShouldShowOnContentChanged();
            }
        }
        if (m_VerticalEnabled)
        {
            if (m_PreviousContentSizeY != m_ScrollRect.content.sizeDelta.y)
            {
                m_PreviousContentSizeY = m_ScrollRect.content.sizeDelta.y;
                CheckShouldShowOnContentChanged();
            }
        }
    }

    private void CheckShouldShowOnContentChanged()
    {
        if (m_HorizontalEnabled)
        {
            RefreshHorizontalArrow();
        }
        if (m_VerticalEnabled)
        {
            RefreshVerticalArrow();
        }
    }

    private void OnScroll(Vector2 value)
    {
        if (m_HorizontalEnabled)
        {
            RefreshHorizontalArrow();
        }
        if (m_VerticalEnabled)
        {
            RefreshVerticalArrow();
        }
    }

    private void RefreshVerticalArrow()
    {
        var verPos = m_ScrollRect.verticalNormalizedPosition;
        if (m_VerticalEnabled && m_ScrollRect.content.rect.height - m_ScrollRect.viewport.rect.height >= 5)
        {
            upArrow.gameObject.SetActive(verPos < 1 - dead);
            downArrow.gameObject.SetActive(verPos > dead);
        }
        else
        {
            upArrow.gameObject.SetActive(false);
            downArrow.gameObject.SetActive(false);
        }
    }

    private void RefreshHorizontalArrow()
    {
        var horPos = m_ScrollRect.horizontalNormalizedPosition;
        if (m_HorizontalEnabled && m_ScrollRect.content.rect.width - m_ScrollRect.viewport.rect.width >= 5)
        {
            rightArrow.gameObject.SetActive(horPos < 1 - dead);
            leftArrow.gameObject.SetActive(horPos > dead);
        }
        else
        {
            rightArrow.gameObject.SetActive(false);
            leftArrow.gameObject.SetActive(false);
        }
    }

    private void OnDestroy()
    {
        if (useTween)
        {
            rightArrow?.DOKill();
            leftArrow?.DOKill();
            downArrow?.DOKill();
            upArrow?.DOKill();
        }
    }
}